
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta charset="utf-8"></meta>
      <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
      <title>13.6.&nbsp;Custom, Cypher Based Procedures and Functions - Chapter&nbsp;13.&nbsp;Cypher Execution</title>
      <link rel="stylesheet" type="text/css" href="../../docbook.css"></link>
      <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,400italic,600,300italic"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/theme/neo.min.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/chunked-base.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/extra.css"></link><script src="//code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script><script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js" type="text/javascript"></script><script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/addon/runmode/runmode.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/mode/cypher/cypher.min.js" type="text/javascript"></script><script src="../../javascript/datatable.js" type="text/javascript"></script><script src="../../javascript/colorize.js" type="text/javascript"></script><script src="../../javascript/tabs-for-chunked.js" type="text/javascript"></script><script src="../../javascript/mp-nav.js" type="text/javascript"></script><script src="../../javascript/versionswitcher.js" type="text/javascript"></script><script src="../../javascript/version.js" type="text/javascript"></script><script src="//s3-eu-west-1.amazonaws.com/alpha.neohq.net/docs/new-manual/assets/search.js" type="text/javascript"></script><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"></meta>
      <link rel="prev" href="../periodic-commit/" title="13.4.&nbsp;apoc.periodic.commit"></link>
      <link rel="next" href="../../virtual/" title="Chapter&nbsp;14.&nbsp;Virtual Nodes &amp; Relationships (Graph Projections)"></link>
      <link rel="shortcut icon" href="https://neo4j.com/wp-content/themes/neo4jweb/favicon.ico"></link><script>
        $(document).ready(function() {
          CodeMirror.colorize();
          tabTheSource($('body'));
          var $header = $('header').first();
          $header.prepend(
            $('<a href="" id="logo"><img src="https://neo4j.com/wp-content/themes/neo4jweb/assets/images/neo4j-logo-2015.png" alt="Neo4j Logo"></img></a>')
          );
          var $sidebar = $('<div id="sidebar-wrapper"></div>');
          $.get('toc.html', function (d){
            $(d).appendTo($sidebar);
            highlightToc();
            highlightLibraryHeader();
          });
          $sidebar.insertAfter($('header').first());
        });
        </script></head>
   <body>
      <header>
         <div class="searchbox">
            <form id="search-form" class="search" name="search-form" role="search"><input id="search-form-input" name="q" title="search" type="search" lang="en" placeholder="Search Neo4j docs..." aria-label="Search Neo4j documentation" max-length="128" required="required"></input><input id="search-form-button" type="submit" value="Search"></input></form>
         </div>
         <ul class="documentation-library">
            <li><a href="https://neo4j.com/docs/operations-manual/current">Operations Manual</a></li>
            <li><a href="https://neo4j.com/docs/developer-manual/current/">Developer Manual</a></li>
            <li><a href="https://neo4j.com/docs/ogm-manual/current/">OGM Manual</a></li>
            <li><a href="https://neo4j.com/docs/graph-algorithms/current/">Graph Algorithms</a></li>
            <li><a href="https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.4/">APOC</a></li>
            <li><a href="https://neo4j.com/docs/java-reference/current/">Java Reference</a></li>
         </ul>
         <nav id="header-nav"><span class="nav-previous"><a accesskey="p" href="../periodic-commit/"><span class="fa fa-long-arrow-left" aria-hidden="true"></span>apoc.periodic.commit</a></span><span class="nav-current">
               <p class="nav-title hidden">13.6.&nbsp;Custom, Cypher Based Procedures and Functions</p></span><span class="nav-next"><a accesskey="n" href="../../virtual/">Virtual Nodes &amp; Relationships (Graph Projections)<span class="fa fa-long-arrow-right" aria-hidden="true"></span></a></span></nav>
      </header>
      <div id="search-results" class="hidden"></div>
      <section class="section" id="cypher-based-procedures-functions">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title" style="clear: both"><a class="anchor" href="#cypher-based-procedures-functions"></a>13.6.&nbsp;Custom, Cypher Based Procedures and Functions
                  </h2>
               </div>
            </div>
         </div>
         <p>I wanted for a long time to be able to register Cypher statements as proper procedures and functions, so that they become
            callable in a standalone way.
         </p>
         <p>You can achieve that with the <code class="literal">apoc.custom.asProcedure</code> and <code class="literal">apoc.custom.asFunction</code> procedure calls.
            Those register a given Cypher statement, prefixed with the <code class="literal">custom.*</code> namespace, overriding potentially existing ones, so you can redefine them as needed.
         </p>
         <p>Here is a simple example:</p><pre class="screen highlight"><code>CALL apoc.custom.asProcedure('answer','RETURN 42 as answer')</code></pre><p>This registers the statement as procedure <code class="literal">custom.answer</code> that you then can call.
            As no information on parameter and return types is given, it just returns a stream of columns of maps called <code class="literal">row</code>.
         </p><pre class="screen highlight"><code>CALL custom.answer YIELD row
RETURN row.answer</code></pre><p>The same is possible as a function:</p><pre class="screen highlight"><code>CALL apoc.custom.asFunction('answer','RETURN 42')</code></pre><div class="admonitionblock note">
            <table>
               <tbody>
                  <tr>
                     <td class="icon"><i class="fa icon-note" title="note"></i></td>
                     <td class="content">
                        <p>If you override procedures or functions you might need to call <code class="literal">call dbms.clearQueryCaches()</code> as lookups to internal id&#8217;s are kept in compiled query plans.
                        </p>
                     </td>
                  </tr>
               </tbody>
            </table>
         </div>
         <section class="section" id="_custom_procedures_with_literal_apoc_custom_asprocedure_literal">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_custom_procedures_with_literal_apoc_custom_asprocedure_literal"></a>13.6.1.&nbsp;Custom Procedures with <code class="literal">apoc.custom.asProcedure</code></h3>
                  </div>
               </div>
            </div>
            <p>Given statement will be registered as a procedure, the results will be turned into a stream of records.</p>
            <div class="table" id="d0e17044">
               <table class="table" summary="Parameters" border="1">
                  <caption class="table-title">Table&nbsp;13.2.&nbsp;Parameters</caption>
                  <colgroup>
                     <col class="col_1"></col>
                     <col class="col_2"></col>
                     <col class="col_3"></col>
                  </colgroup>
                  <thead>
                     <tr>
                        <th style="text-align: left; vertical-align: top; ">name</th>
                        <th style="text-align: left; vertical-align: top; ">default</th>
                        <th style="text-align: left; vertical-align: top; ">description</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">name</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">none</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>dot-separated name, will be prefixed with <code class="literal">custom</code></p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">statement</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">none</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>cypher statement to run, can use $parameters</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">mode</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">read</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>execution mode of the procedure: read, write, or schema</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">outputs</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[["row","MAP"]]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>List of pairs of name-type to be used as output columns, need to be in-order with the cypher statement, the default is a special
                              case, that will collect all columns of the statement result into a map
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">inputs</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[["params","MAP","{}"]]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Pairs or triples of name-type-default, to be used as input parameters. The default just takes an optional map, otherwise they
                              will become proper paramters in order
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">description</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">""</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>A general description about the business rules implemented into the procedure</p>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </div>
            <p>The type names are what you would expect and see in outputs of <code class="literal">dbms.procedures</code> or <code class="literal">apoc.help</code> just without the <code class="literal">?</code>.
               The default values are parsed as JSON.
            </p>
            <div class="itemizedlist">
               <div class="itemizedlist-title">Type Names</div>
               <ul class="itemizedlist" style="list-style-type: disc; ">
                  <li class="listitem">FLOAT, DOUBLE, INT, INTEGER, NUMBER, LONG</li>
                  <li class="listitem">TEXT, STRING</li>
                  <li class="listitem">BOOL, BOOLEAN</li>
                  <li class="listitem">POINT, GEO, GEOCORDINATE</li>
                  <li class="listitem">DATE, DATETIME, LOCALDATETIME, TIME, LOCALTIME, DURATION</li>
                  <li class="listitem">NODE, REL, RELATIONSHIP, PATH</li>
                  <li class="listitem">MAP</li>
                  <li class="listitem">LIST TYPE, LIST OF TYPE</li>
                  <li class="listitem">ANY</li>
               </ul>
            </div>
            <p><span class="formalpara-title">Example Neighbours of a node by name.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">CALL apoc.custom.asProcedure('neighbours',
  'MATCH (n:Person {name:$name})--&gt;(nb) RETURN nb as neighbour','read',
  [['neighbour','NODE']],[['name','STRING'], 'get neighbours of a person']);

CALL custom.neighbours('Keanu Reeves') YIELD neighbour;</code></pre><p>
               
            </p>
         </section>
         <section class="section" id="_custom_functions_with_literal_apoc_custom_asfunction_literal">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_custom_functions_with_literal_apoc_custom_asfunction_literal"></a>13.6.2.&nbsp;Custom Functions with <code class="literal">apoc.custom.asFunction</code></h3>
                  </div>
               </div>
            </div>
            <p>Given statement will be registered as a statement, the results into a single value.
               If the given output type is a list, results will be collected into a list, otherwise the first row will be used.
               The statement needs to return a single column, otherwise an error is thrown.
            </p>
            <div class="table" id="d0e17190">
               <table class="table" summary="Parameters" border="1">
                  <caption class="table-title">Table&nbsp;13.3.&nbsp;Parameters</caption>
                  <colgroup>
                     <col class="col_1"></col>
                     <col class="col_2"></col>
                     <col class="col_3"></col>
                  </colgroup>
                  <thead>
                     <tr>
                        <th style="text-align: left; vertical-align: top; ">name</th>
                        <th style="text-align: left; vertical-align: top; ">default</th>
                        <th style="text-align: left; vertical-align: top; ">description</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">name</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">none</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>dot-separated name, will be prefixed with <code class="literal">custom</code></p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">statement</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">none</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>cypher statement to run, can use $parameters</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">outputs</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">"LIST OF MAP"</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Output type for single output, if the type is a list, then all rows will be collected, otherwise just the first row. Only
                              single column results are allowed.
                              If your single row result is a list you can force a single row by setting the last parameter to <code class="literal">true</code></p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">inputs</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[["params","MAP","{}"]]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Pairs or triples of name-type-default, to be used as input parameters. The default just takes an optional map, otherwise they
                              will become proper paramters in order
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">singleRow</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">false</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>If set to true, the statement is treated as single row even with the list result type, then your statement has to return a
                              list.
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">description</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">""</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>A general description about the business rules implemented into the function</p>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </div>
            <p>The type names are what you would expect and see in outputs of <code class="literal">dbms.procedures</code> or <code class="literal">apoc.help</code> just without the <code class="literal">?</code>.
               The default values are parsed as JSON.
            </p>
         </section>
         <section class="section" id="_list_of_registered_procedures_function_with_literal_apoc_custom_list_literal">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_list_of_registered_procedures_function_with_literal_apoc_custom_list_literal"></a>13.6.3.&nbsp;List of registered procedures/function with <code class="literal">apoc.custom.list</code></h3>
                  </div>
               </div>
            </div>
            <p>The procedure <code class="literal">apoc.custom.list</code> provide a list of all registered procedures/function via
               <code class="literal">apoc.custom.asProcedure</code> and <code class="literal">apoc.custom.asFunction</code></p>
            <p>Given the this call:</p><pre class="programlisting highlight"><code data-lang="cypher">CALL apoc.custom.list</code></pre><p>The the output will look like the following table:</p>
            <div class="informaltable">
               <div class="table" id="d0e17314">
                  <table class="informaltable" border="1">
                     <colgroup>
                        <col class="col_1"></col>
                        <col class="col_2"></col>
                        <col class="col_3"></col>
                        <col class="col_4"></col>
                        <col class="col_5"></col>
                        <col class="col_6"></col>
                        <col class="col_7"></col>
                        <col class="col_8"></col>
                     </colgroup>
                     <thead>
                        <tr>
                           <th style="text-align: left; vertical-align: top; ">type</th>
                           <th style="text-align: left; vertical-align: top; ">name</th>
                           <th style="text-align: left; vertical-align: top; ">description</th>
                           <th style="text-align: left; vertical-align: top; ">mode</th>
                           <th style="text-align: left; vertical-align: top; ">statement</th>
                           <th style="text-align: left; vertical-align: top; ">inputs</th>
                           <th style="text-align: left; vertical-align: top; ">outputs</th>
                           <th style="text-align: left; vertical-align: top; ">forceSingle</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"function"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"answer"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>&lt;null&gt;</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>&lt;null&gt;</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"RETURN $input as answer"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>[["input","number"]]</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"long"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>false</p>
                           </td>
                        </tr>
                        <tr>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"procedure"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"answer"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"Procedure that answer to the Ultimate Question of Life, the Universe, and Everything"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"read"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>"RETURN $input as answer"</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>[["input","int","42"]]</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>[["answer","number"]]</p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>&lt;null&gt;</p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </div>
            </div>
         </section>
         <section class="section" id="_how_to_manage_procedure_function_replication_in_a_causal_cluster">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_how_to_manage_procedure_function_replication_in_a_causal_cluster"></a>13.6.4.&nbsp;How to manage procedure/function replication in a Causal Cluster
                     </h3>
                  </div>
               </div>
            </div>
            <p>In order to replicate the procedure/function in a cluster environment you can tune the following parameters:</p>
            <div class="informaltable">
               <div class="table" id="d0e17398">
                  <table class="informaltable" border="1">
                     <colgroup>
                        <col class="col_1"></col>
                        <col class="col_2"></col>
                        <col class="col_3"></col>
                     </colgroup>
                     <thead>
                        <tr>
                           <th style="text-align: left; vertical-align: top; ">name</th>
                           <th style="text-align: left; vertical-align: top; ">type</th>
                           <th style="text-align: left; vertical-align: top; ">description</th>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                           <td style="text-align: left; vertical-align: top; ">
                              <p><code class="literal">apoc.custom.procedures.refresh</code></p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>long (default <code class="literal">60000</code>)
                              </p>
                           </td>
                           <td style="text-align: left; vertical-align: top; ">
                              <p>the refresh time that allows replicating the procedure/function
                                 changes to each cluster member
                              </p>
                           </td>
                        </tr>
                     </tbody>
                  </table>
               </div>
            </div>
         </section>
      </section>
      <footer><script type="text/javascript">
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
          //Allow Linker
          ga('create', 'UA-1192232-34','auto', {'allowLinker': true});
          ga('send', 'pageview');
          // Load the plugin.
          ga('require', 'linker');
          // Define which domains to autoLink.
          ga('linker:autoLink', ['neo4j.org','neo4j.com','neotechnology.com','graphdatabases.com','graphconnect.com']);
        </script><script type="text/javascript">
          document.write(unescape("%3Cscript src='//munchkin.marketo.net/munchkin.js' type='text/javascript'%3E%3C/script%3E"));
        </script><script>Munchkin.init('773-GON-065');</script></footer>
   </body>
</html>